package com.travel.server.manager.impl.dal;

import com.travel.common.exception.WorkCode;
import com.travel.common.exception.WorkException;
import com.travel.common.util.CollectionUtil;
import com.travel.server.manager.dao.ProjectSpecialDao;
import com.travel.server.manager.model.ProjectSpecial;
import com.travel.server.manager.model.ProjectSpecialExample;
import com.travel.server.manager.model.dto.SpecialEnumDto;
import com.travel.server.manager.model.dto.data.OrderCostItemDto;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * @Author: LiZhenhui
 * @Date: 2018/10/29 11:18
 * @Desc:
 */
@Component
@Slf4j
public class SpecialDal {

    @Autowired
    private ProjectSpecialDao projectSpecialDao;

    public ProjectSpecial selectById(Integer id){
        ProjectSpecial projectSpecial = projectSpecialDao.selectByPrimaryKey(id);
        if(projectSpecial == null){
            log.info("未查询到项目规格信息, id {}", id);
            throw new WorkException(WorkCode.RECORD_NOT_EXIST);
        }
        return projectSpecial;
    }

    public PageDto<ProjectSpecial> select(SpecialParam param){
        ProjectSpecialExample example = makeExample(param);
        int total = projectSpecialDao.countByExample(example);
        example.setOrderByClause("update_time desc");
        List<ProjectSpecial> list = projectSpecialDao.selectByExample(example);

        PageDto<ProjectSpecial> pageDto = new PageDto<>();
        pageDto.setTotal(total);
        pageDto.setList(list);
        return pageDto;
    }

    public ProjectSpecial select(Integer projectId, Date travelDate){
        ProjectSpecialExample example = new ProjectSpecialExample();
        ProjectSpecialExample.Criteria criteria = example.or();
        criteria.andProjectIdEqualTo(projectId);
        criteria.andTravelDateEqualTo(travelDate);
        example.setOrderByClause("state desc");
        return CollectionUtil.getFirst(projectSpecialDao.selectByExample(example));
    }

    public void deleteAllByProjectId(Integer projectId){
        projectSpecialDao.deleteByProjectId(projectId);
    }

    public List<OrderCostItemDto> selectOrderCostItem(Date startTime, Date endTime){
        return projectSpecialDao.selectOrderCostItem(startTime, endTime);
    }

    public int selectMonthCost(Date startTime, Date endTime){
        int orderDiscount = projectSpecialDao.selectOrderDiscount(startTime, endTime, null);
        int cost = projectSpecialDao.selectSpecialCost(startTime, endTime);
        return orderDiscount + cost;
    }

    public int selectOrderDiscount(Integer specialId){
        return projectSpecialDao.selectOrderDiscount(null, null, specialId);
    }

    public List<ProjectSpecial> selectByExample(SpecialParam param){
        ProjectSpecialExample example = makeExample(param);
        example.setOrderByClause("update_time desc");
        return projectSpecialDao.selectByExample(example);
    }

    public List<SpecialEnumDto> selectEnum(List<Integer> projectIdList){
        return projectSpecialDao.selectEnum(projectIdList);
    }

    public List<ProjectSpecial> selectSpecial(Date startTime, Date endTime, Integer offset, Integer limit){
        SpecialParam param = new SpecialParam();
        param.setStartTime(startTime);
        param.setEndTime(endTime);
        param.setStartRow(offset);
        param.setLimit(limit);
        return selectByExample(param);
    }

    public int selectSpecialCount(Date startTime, Date endTime){
        SpecialParam param = new SpecialParam();
        param.setStartTime(startTime);
        param.setEndTime(endTime);
        ProjectSpecialExample example = makeExample(param);
        return projectSpecialDao.countByExample(example);
    }

    private ProjectSpecialExample makeExample(SpecialParam param){
        ProjectSpecialExample example = new ProjectSpecialExample();
        ProjectSpecialExample.Criteria criteria = example.or();
        if(!CollectionUtil.isEmpty(param.getProjectIdList())){
            criteria.andProjectIdIn(param.getProjectIdList());
        }
        if(StringUtils.isNotBlank(param.getDays())){
            criteria.andDaysEqualTo(param.getDays());
        }
        if(param.getState() != null){
            criteria.andStateEqualTo(param.getState());
        }
        if(!CollectionUtil.isEmpty(param.getIdList())){
            criteria.andIdIn(param.getIdList());
        }
        if(param.getTravelDate() != null){
            criteria.andTravelDateEqualTo(param.getTravelDate());
        }
        if(param.getStartTime() != null && param.getEndTime() != null){
            criteria.andTravelDateBetween(param.getStartTime(), param.getEndTime());
        }
        if(param.getStartRow() != null){
            example.setOffset(param.getStartRow());
        }
        if(param.getLimit() != null){
            example.setLimit(param.getLimit());
        }
        return example;
    }

    public void insertOrUpdate(ProjectSpecial projectSpecial){
        if(projectSpecial.getId() != null){
            projectSpecialDao.updateByPrimaryKey(projectSpecial);
        }else{
            projectSpecialDao.insertSelective(projectSpecial);
        }
    }

    public void updateByDays(String arrangeExplains, String days, Integer projectId, String updateBy){
        projectSpecialDao.updateByDays(arrangeExplains, days, projectId, updateBy);
    }

    @Data
    public static class SpecialParam{
        private List<Integer> projectIdList;

        private List<Integer> idList;

        private String days;

        private Date travelDate;

        private Date startTime;

        private Date endTime;

        private Integer startRow;

        private Integer limit;

        private Integer state = 1;
    }
}
